home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
edit
/
pt20pc.zip
/
FIND.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-04
|
10KB
|
405 lines
#include "pt.h"
void pascal
/* XTAG:xyToPos */
xyToPos(inRow, inCol, where, pos, wOut)
int *inRow, *inCol;
register int *where;
long *pos;
struct window **wOut;
{
extern unsigned char msgBuffer[];
extern struct window *windowList;
extern int tabWidth;
extern int debug;
extern int menuLine;
extern int scrRows, scrCols;
register struct window *w;
long cp, cp2;
int n, tabStop, rowsDown, iBuffer, iLine;
int row, col;
int doRowCache, eofFlag;
unsigned char ch, nullChar;
unsigned char far *firstByte;
unsigned char far *lastByte;
eofFlag = 0;
row = *inRow;
if( (menuLine > 0 && row == 0)
|| (menuLine < 0 && row == (scrRows-1)) ) {
*where = TOPLINE;
*wOut = NULL;
return;
}
col = *inCol;
w = windowList;
do {
/* see if this screen coordinate is in this window */
/* above this window? */
if( row < w->row1 )
continue;
/* below this window? */
if( row > w->row2 )
continue;
/* left of this window? */
if( col < w->col1 )
continue;
/* right of this window? */
if( col > w->col2 )
continue;
/* it is this window so return its address */
*wOut = w;
/* on the upper border? */
if( row == w->row1 ) {
if( col == w->col1 )
*where = UPPERLEFT;
else if( w->col2 == col )
*where = UPPERRIGHT;
else
*where = UPPERBORDER;
}
/* one the lower border? */
else if( row == w->row2 ) {
if( col == w->col1 )
*where = LOWERLEFT;
else if( col == w->col2 )
*where = LOWERRIGHT;
else
*where = LOWERBORDER;
}
/* on the left border? */
else if( col == w->col1 )
*where = LEFTBORDER;
/* on the right border? */
else if( col == w->col2 )
*where = RIGHTBORDER;
/* else it must be inside */
else {
*where = INSIDEWINDOW;
rowsDown = row - w->row1 - 1; /* rows down */
/* has window moved since we last found a line? */
doRowCache = 1;
if( w->lastPosTop == w->posTopline ) {
/* if so find the new line relative to it */
cp = w->posCurLast;
rowsDown -= w->rowCurLast;
if( rowsDown < 0 ) {
rowsDown = -rowsDown;
cp=prevLine(w->fileId,cp,&rowsDown);
} else if( rowsDown > 0 )
goto countDown;
} else {
/* just count down from the top line */
cp = w->posTopline;
countDown:
n = rowsDown;
cp = nextLine(w->fileId, cp, &rowsDown);
/* fix so that EOF works */
if( (n -= rowsDown) > 0 ) {
*inRow -= n;
doRowCache = 0;
}
/* see if EOF on a line alone */
if( (cp-1) > 0 &&
readChar(w->fileId,cp-1)!='\n') {
/* another fix so EOF works */
--*inRow;
doRowCache = 0;
}
}
/* if we are near end of file, "row" and the */
/* "cp" will not really be right. The +3 is */
/* superstitious but I want to be sure we don't get */
/* get off on the counts. There is little need */
/* to optimize at the end of the file, we can forgo */
/* that to be safe */
if( (cp + 3 < fileSize(w->fileId)) && doRowCache ) {
/* compute the number of rows down */
w->rowCurLast = row - w->row1 - 1;
w->posCurLast = cp;
w->lastPosTop = w->posTopline;
} else
w->lastPosTop = -1;
n = col - w->col1 - 1 + w->indent;
iBuffer = 0;
iLine = 0;
firstByte = (unsigned char far *)1;
lastByte = (unsigned char far *)0;
cp2 = cp;
while( iLine <= n ) {
if( firstByte > lastByte ) {
if(getSpan(w->fileId, cp2, &firstByte,
&lastByte, 0) ) {
nullChar = 0;
eofFlag = 1;
firstByte = &nullChar;
lastByte = firstByte;
}
}
++cp2;
++iBuffer;
ch = *firstByte++;
switch( ch ) {
case '\n': /* end of line */
goto endLoop;
case 0: /* end of file */
if( eofFlag )
goto endLoop;
else
goto justACharacter;
case '\t':
tabStop = iLine + tabWidth
- (iLine % tabWidth);
if( tabStop > n )
goto endLoop;
else
iLine = tabStop;
break;
case '\r': /* ignore CRs */
/* unless they are not followed */
/* by a NL */
if( *firstByte == '\n' )
break;
/* else drop through */
default:
justACharacter:
iLine++;
break;
}
}
endLoop:
*pos = cp + iBuffer - 1;
}
return;
} while( (w = w->nextWindow) != NULL );
*where = OUTSIDEWINDOW;
*wOut = NULL;
}
long pascal
/* XTAG:xyToWindow */
xyToWindow(w, inRow, inCol)
register struct window *w;
int *inRow, *inCol;
{
extern unsigned char msgBuffer[];
extern unsigned char textBuffer[];
extern struct window *windowList;
extern int tabWidth;
extern int debug;
long cp, cp2;
int n, tabStop, rowsDown, iBuffer, iLine;
int row, col;
int doRowCache, eofFlag;
unsigned char ch, nullChar;
unsigned char far *firstByte;
unsigned char far *lastByte;
eofFlag = 0;
row = *inRow;
col = *inCol;
/* handle the cases where the cursor is outside of the window */
/* return the nearest character in the window */
/* if above or below, use the nearest line */
if( row <= w->row1 )
row = w->row1 + 1;
else if( row >= w->row2 )
row = w->row2 - 1;
/* if to the side, use the nearest column */
if( col <= w->col1 )
col = w->col1 + 1;
else if( col >= w->col2 )
col = w->col2 - 1;
/* now find the character position in the file */
rowsDown = row - w->row1 - 1;
/* rows down from the top line displayed in the window */
doRowCache = 1;
/* Has the window text moved since we last found a line? */
if( w->lastPosTop == w->posTopline ) {
/* if so find the new line relative to it */
cp = w->posCurLast;
rowsDown -= w->rowCurLast;
/* adjust rows down by where the cached line is */
if( rowsDown < 0 ) {
/* line to find is above the cached line */
rowsDown = -rowsDown;
cp = prevLine(w->fileId, cp, &rowsDown);
} else if( rowsDown > 0 )
/* line to find is below the cached line */
goto countDown;
/* count down the lines from the cached line */
} else {
/* if not, just count down from the top line */
cp = w->posTopline;
countDown:
n = rowsDown; /* remember how many we asked to count down */
cp = nextLine(w->fileId, cp,
&rowsDown);
/* fix so that EOF works */
/* rowsDown is how many nextLine actually went down */
/* if n > rowsDown then we hit EOF */
if( (n -= rowsDown) > 0 ) {
/* tell the caller the hit was below the last line */
*inRow -= n;
doRowCache = 0;
}
/* see if the EOF marker NOT is on a line alone */
/* this will be try if nextLine stopped at the EOF marker */
/* and the last real character is NOT a newline */
/* The first test is a fix when you are at the beginning */
/* of the file */
if( cp != 0L && readChar(w->fileId, cp-1) != '\n' ) {
/* another fix so that EOF works */
--*inRow;
doRowCache = 0;
}
}
/* if we are near the end of file the "row" and the "cp" */
/* will not really be right. The +3 is superstitious but */
/* I want to be sure we don't get off on the counts. There */
/* is little need to optimize at the end of the file, we */
/* can forgo that to be safe */
if( (cp + 3 < fileSize(w->fileId)) && doRowCache ) {
w->rowCurLast = row - w->row1 - 1; /* rows down */
w->posCurLast = cp;
w->lastPosTop = w->posTopline;
} else
w->lastPosTop = -1;
/* figure out the physical column */
n = col - w->col1 - 1 + w->indent;
/* now we have to figure out the text file position by */
/* reconstructing the line */
iBuffer = 0;
iLine = 0;
firstByte = (unsigned char far *)1;
lastByte = (unsigned char far *)0;
cp2 = cp;
while( iLine <= n ) {
if( firstByte > lastByte ) {
if(getSpan(w->fileId, cp2, &firstByte, &lastByte,0)){
nullChar = 0;
eofFlag = 1;
firstByte = &nullChar;
lastByte = firstByte;
}
}
++cp2;
++iBuffer;
ch = *firstByte++;
switch( ch ) {
case '\n': /* end of line */
goto endLoop;
case 0: /* end of file */
if( eofFlag )
goto endLoop;
else
goto justACharacter;
case '\t':
tabStop = iLine + tabWidth - (i